home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume16 / pcomm2 / part05 < prev    next >
Encoding:
Internet Message Format  |  1988-09-14  |  50.6 KB

  1. Path: bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v16i010:  Modem communications package, Part05/08
  5. Message-ID: <1062@fig.bbn.com>
  6. Date: 13 Sep 88 16:43:52 GMT
  7. Lines: 2078
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: Emmet P Gray <fthood!egray>
  11. Posting-number: Volume 16, Issue 10
  12. Archive-name: pcomm2/part05
  13.  
  14. #! /bin/sh
  15. # This is a shell archive, meaning:
  16. # 1. Remove everything above the #! /bin/sh line.
  17. # 2. Save the resulting text in a file.
  18. # 3. Execute the file with /bin/sh (not csh) to create:
  19. #    m_lib.c
  20. #    macro.c
  21. #    main.c
  22. #    n_shell.c
  23. #    p_lib.c
  24. #    passthru.c
  25. #    pexit.c
  26. #    port.c
  27. #    redial.c
  28. export PATH; PATH=/bin:/usr/bin:$PATH
  29. echo shar: "extracting 'm_lib.c'" '(10070 characters)'
  30. if test -f 'm_lib.c'
  31. then
  32.     echo shar: "will not over-write existing file 'm_lib.c'"
  33. else
  34. sed 's/^X//' << \SHAR_EOF > 'm_lib.c'
  35. X/*
  36. X * Routines to manipulate the pcomm.modem file
  37. X */
  38. X
  39. X#include <stdio.h>
  40. X#include "modem.h"
  41. X
  42. X/*
  43. X * Read the modem/TTY database file.  Returns a pointer to a static area
  44. X * containing the MODEM structure.  All modem entries and all TTY entries
  45. X * are created regardless of the number of physical entries in the file.
  46. X */
  47. X
  48. Xstruct MODEM *
  49. Xread_modem(extra)
  50. Xchar *extra;
  51. X{
  52. X    extern char *null_ptr;
  53. X    FILE *fp, *my_fopen();
  54. X    int i, tty, mod, line, oops, m_line, start, stop;
  55. X    char *strdup(), buf[200], message[80], token[40], *str_tok(), *str;
  56. X    char *temp_token, *t_sep, *m_sep, *m_letter, *findfile();
  57. X    static struct MODEM m;
  58. X    void error_win();
  59. X
  60. X    if ((m.m_path = findfile(extra, "pcomm.modem")) == NULL)
  61. X        error_win(1, "Support file 'pcomm.modem' is missing", "or no read permission");
  62. X                    /* read permission checked */
  63. X    fp = my_fopen(m.m_path, "r");
  64. X
  65. X    t_sep = ";;\n";
  66. X    m_sep = ";;;;\n;;;;;;\n;;;\n";
  67. X    m_letter = "abc";
  68. X    oops = 0;
  69. X    tty = 0;
  70. X    mod = 0;
  71. X    line = 0;
  72. X    m_line = 0;
  73. X    while (fgets(buf, 200, fp) != NULL) {
  74. X        line++;
  75. X        if (tty >= NUM_TTY || mod >= NUM_MODEM)
  76. X            break;
  77. X                    /* get the token */
  78. X        if (!(temp_token = str_tok(buf, '='))) {
  79. X            sprintf(message, "is missing a token at line %d", line);
  80. X            oops++;
  81. X            break;
  82. X        }
  83. X        if (*temp_token != 'T' && *temp_token != 'M') {
  84. X            sprintf(message, "is corrupted at line %d", line);
  85. X            oops++;
  86. X            break;
  87. X        }
  88. X                    /* the TTY database */
  89. X        if (*temp_token == 'T') {
  90. X            /*
  91. X             * This is similar to the "real" strtok() command
  92. X             * but this one returns a null pointer on a missing
  93. X             * attribute.  Note the use of the field separator
  94. X             * array.
  95. X             */
  96. X            for (i=0; i<3; i++) {
  97. X                if (!(str = str_tok((char *) NULL, t_sep[i]))) {
  98. X                    sprintf(message, "is missing a parameter at line %d", line);
  99. X                    oops++;
  100. X                    break;
  101. X                }
  102. X                switch (i) {
  103. X                    case 0:
  104. X                        m.tty[tty] = strdup(str);
  105. X                        break;
  106. X                    case 1:
  107. X                        m.tname[tty] = strdup(str);
  108. X                        break;
  109. X                    case 2:
  110. X                        m.init_sp[tty] = atoi(str);
  111. X                        break;
  112. X                }
  113. X            }
  114. X            if (oops)
  115. X                break;
  116. X                    /* sanity checking */
  117. X            sprintf(token, "TTY_%d", tty+1);
  118. X            if (strcmp(token, temp_token)) {
  119. X                sprintf(message, "is corrupted at line %d", line);
  120. X                oops++;
  121. X                break;
  122. X            }
  123. X            tty++;
  124. X            continue;
  125. X        }
  126. X                    /* the modem database */
  127. X        else {
  128. X            sprintf(token, "MODEM_%d%c", mod+1, m_letter[m_line]);
  129. X            if (strcmp(token, temp_token)) {
  130. X                sprintf(message, "is corrupted at line %d", line);
  131. X                oops++;
  132. X                break;
  133. X            }
  134. X            /*
  135. X             * There are three lines to the modem database.  They
  136. X             * are distinguished by the letters a, b, and, c
  137. X             * appended to the entry number.
  138. X             */
  139. X            switch (m_line) {
  140. X                case 0:
  141. X                    start = 0;
  142. X                    stop = 5;
  143. X                    break;
  144. X                case 1:
  145. X                    start = 5;
  146. X                    stop = 12;
  147. X                    break;
  148. X                case 2:
  149. X                    start = 12;
  150. X                    stop = 16;
  151. X                    break;
  152. X            }
  153. X            for (i=start; i<stop; i++) {
  154. X                if (!(str = str_tok((char *) NULL, m_sep[i]))) {
  155. X                    sprintf(message, "is missing a parameter at line %d", line);
  156. X                    oops++;
  157. X                    break;
  158. X                }
  159. X                switch (i) {
  160. X                    case 0:
  161. X                        m.mname[mod] = strdup(str);
  162. X                        break;
  163. X                    case 1:
  164. X                        m.init[mod] = strdup(str);
  165. X                        break;
  166. X                    case 2:
  167. X                        m.dial[mod] = strdup(str);
  168. X                        break;
  169. X                    case 3:
  170. X                        m.suffix[mod] = strdup(str);
  171. X                        break;
  172. X                    case 4:
  173. X                        m.hang_up[mod] = strdup(str);
  174. X                        break;
  175. X                    case 5:
  176. X                        m.auto_baud[mod] = *str;
  177. X                        break;
  178. X                    case 6:
  179. X                        m.con_3[mod] = strdup(str);
  180. X                        break;
  181. X                    case 7:
  182. X                        m.con_12[mod] = strdup(str);
  183. X                        break;
  184. X                    case 8:
  185. X                        m.con_24[mod] = strdup(str);
  186. X                        break;
  187. X                    case 9:
  188. X                        m.con_48[mod] = strdup(str);
  189. X                        break;
  190. X                    case 10:
  191. X                        m.con_96[mod] = strdup(str);
  192. X                        break;
  193. X                    case 11:
  194. X                        m.con_192[mod] = strdup(str);
  195. X                        break;
  196. X                    case 12:
  197. X                        m.no_con1[mod] = strdup(str);
  198. X                        break;
  199. X                    case 13:
  200. X                        m.no_con2[mod] = strdup(str);
  201. X                        break;
  202. X                    case 14:
  203. X                        m.no_con3[mod] = strdup(str);
  204. X                        break;
  205. X                    case 15:
  206. X                        m.no_con4[mod] = strdup(str);
  207. X                        break;
  208. X                }
  209. X            }
  210. X            if (oops)
  211. X                break;
  212. X            m_line++;
  213. X            if (m_line >= 3) {
  214. X                m_line = 0;
  215. X                mod++;
  216. X            }
  217. X        }
  218. X    }
  219. X    fclose(fp);
  220. X
  221. X    if (oops) {
  222. X        sprintf(buf, "Modem/TTY database file '%s'", m.m_path);
  223. X        error_win(1, buf, message);
  224. X    }
  225. X    m.t_entries = tty;
  226. X    m.m_entries = mod;
  227. X    m.t_cur = -1;
  228. X    m.m_cur = -1;
  229. X                    /* if empty database */
  230. X    if (!tty) {
  231. X        sprintf(buf, "Modem/TTY database file '%s'", m.m_path);
  232. X        error_win(0, buf, "has no TTY data");
  233. X    }
  234. X    if (!mod) {
  235. X        sprintf(buf, "Modem/TTY database file '%s'", m.m_path);
  236. X        error_win(0, buf, "has no modem data");
  237. X    }
  238. X                    /* fill in the rest */
  239. X    for (; tty<NUM_TTY; tty++) {
  240. X        m.tty[tty] = null_ptr;
  241. X        m.tname[tty] = null_ptr;
  242. X        m.init_sp[tty] = 0;
  243. X    }
  244. X    for (; mod<NUM_MODEM; mod++) {
  245. X        m.mname[mod] = null_ptr;
  246. X        m.init[mod] = null_ptr;
  247. X        m.dial[mod] = null_ptr;
  248. X        m.suffix[mod] = null_ptr;
  249. X        m.hang_up[mod] = null_ptr;
  250. X
  251. X        m.auto_baud[mod] = 'Y';
  252. X        m.con_3[mod] = null_ptr;
  253. X        m.con_12[mod] = null_ptr;
  254. X        m.con_24[mod] = null_ptr;
  255. X        m.con_48[mod] = null_ptr;
  256. X        m.con_96[mod] = null_ptr;
  257. X        m.con_192[mod] = null_ptr;
  258. X
  259. X        m.no_con1[mod] = null_ptr;
  260. X        m.no_con2[mod] = null_ptr;
  261. X        m.no_con3[mod] = null_ptr;
  262. X        m.no_con4[mod] = null_ptr;
  263. X    }
  264. X    return(&m);
  265. X}
  266. X
  267. X/*
  268. X * Update the modem database.  Other routines actually do the changes
  269. X * or deletions in memory.  A return code of 1 means non-fatal error.
  270. X */
  271. X
  272. Xint
  273. Xup_modem()
  274. X{
  275. X    FILE *fp, *my_fopen();
  276. X    char buf[80];
  277. X    int i;
  278. X    void error_win();
  279. X
  280. X                    /* open for write */
  281. X    if (!(fp = my_fopen(modem->m_path, "w"))) {
  282. X        sprintf(buf, "'%s'", modem->m_path);
  283. X        error_win(0, "No write permission on modem/TTY database file", buf);
  284. X        return(1);
  285. X    }
  286. X                    /* put back the TTY entries */
  287. X    for (i=0; i<modem->t_entries; i++)
  288. X        fprintf(fp, "TTY_%d=%s;%s;%d\n", i+1, modem->tty[i],
  289. X         modem->tname[i], modem->init_sp[i]);
  290. X
  291. X                    /* put back the modem entries */
  292. X    for (i=0; i<modem->m_entries; i++) {
  293. X        fprintf(fp, "MODEM_%da=%s;%s;%s;%s;%s\n", i+1, modem->mname[i],
  294. X         modem->init[i], modem->dial[i], modem->suffix[i],
  295. X         modem->hang_up[i]);
  296. X
  297. X        fprintf(fp, "MODEM_%db=%c;%s;%s;%s;%s;%s;%s\n", i+1,
  298. X         modem->auto_baud[i], modem->con_3[i], modem->con_12[i],
  299. X         modem->con_24[i], modem->con_48[i], modem->con_96[i],
  300. X         modem->con_192[i]);
  301. X
  302. X        fprintf(fp, "MODEM_%dc=%s;%s;%s;%s\n", i+1, modem->no_con1[i],
  303. X         modem->no_con2[i], modem->no_con3[i], modem->no_con4[i]);
  304. X    }
  305. X
  306. X    fclose(fp);
  307. X    return(0);
  308. X}
  309. X
  310. X/*
  311. X * See if the new modem is already in the database.  If it's not, create
  312. X * a slot for it and update the modem->m_cur variable.
  313. X */
  314. X
  315. Xvoid
  316. Xcreate_modem(str)
  317. Xchar *str;
  318. X{
  319. X    int i;
  320. X    char *strdup(), buf[80];
  321. X    void error_win(), free_ptr();
  322. X                    /* modem entry already exists? */
  323. X    for (i=0; i<modem->m_entries; i++) {
  324. X        if (!strcmp(str, modem->mname[i]))
  325. X            return;
  326. X    }
  327. X                    /* empty slot available? */
  328. X    if (modem->m_entries == NUM_MODEM) {
  329. X        sprintf(buf, "'%s'", modem->m_path);
  330. X        error_win(0, "No empty modem slots in", buf);
  331. X        return;
  332. X    }
  333. X                    /* create a new entry */
  334. X    free_ptr(modem->mname[modem->m_entries]);
  335. X    modem->mname[modem->m_entries] = strdup(str);
  336. X
  337. X                    /* update number of entries */
  338. X    modem->m_entries++;
  339. X    return;
  340. X}
  341. X
  342. X/*
  343. X * See if the modem names in the list still need to be in the database.
  344. X * If you find a "lost" entry, delete it and collapse the list.
  345. X */
  346. X
  347. Xvoid
  348. Xdel_modem()
  349. X{
  350. X    extern char *null_ptr;
  351. X    int i, j, match;
  352. X    char *strdup();
  353. X    void free_ptr();
  354. X
  355. X    for (i=0; i<modem->m_entries; i++) {
  356. X        match = 0;
  357. X        for (j=0; j<modem->t_entries; j++) {
  358. X            if (!strcmp(modem->mname[i], modem->tname[j])) {
  359. X                match++;
  360. X                break;
  361. X            }
  362. X        }
  363. X                    /* found a "lost" modem name */
  364. X        if (!match) {
  365. X            for (j=i; j<modem->m_entries-1; j++) {
  366. X                free_ptr(modem->mname[j]);
  367. X                free_ptr(modem->init[j]);
  368. X                free_ptr(modem->dial[j]);
  369. X                free_ptr(modem->suffix[j]);
  370. X                free_ptr(modem->hang_up[j]);
  371. X
  372. X                free_ptr(modem->con_3[j]);
  373. X                free_ptr(modem->con_12[j]);
  374. X                free_ptr(modem->con_24[j]);
  375. X                free_ptr(modem->con_48[j]);
  376. X                free_ptr(modem->con_96[j]);
  377. X                free_ptr(modem->con_192[j]);
  378. X
  379. X                free_ptr(modem->no_con1[j]);
  380. X                free_ptr(modem->no_con2[j]);
  381. X                free_ptr(modem->no_con3[j]);
  382. X                free_ptr(modem->no_con4[j]);
  383. X
  384. X                    /* copy the info */
  385. X                modem->mname[j] = strdup(modem->mname[j+1]);
  386. X                modem->init[j] = strdup(modem->init[j+1]);
  387. X                modem->dial[j] = strdup(modem->dial[j+1]);
  388. X                modem->suffix[j] = strdup(modem->suffix[j+1]);
  389. X                modem->hang_up[j] = strdup(modem->hang_up[j+1]);
  390. X
  391. X                modem->auto_baud[j] = modem->auto_baud[j+1];
  392. X                modem->con_3[j] = strdup(modem->con_3[j+1]);
  393. X                modem->con_12[j] = strdup(modem->con_12[j+1]);
  394. X                modem->con_24[j] = strdup(modem->con_24[j+1]);
  395. X                modem->con_48[j] = strdup(modem->con_48[j+1]);
  396. X                modem->con_96[j] = strdup(modem->con_96[j+1]);
  397. X                modem->con_192[j] = strdup(modem->con_192[j+1]);
  398. X
  399. X                modem->no_con1[j] = strdup(modem->no_con1[j+1]);
  400. X                modem->no_con2[j] = strdup(modem->no_con2[j+1]);
  401. X                modem->no_con3[j] = strdup(modem->no_con3[j+1]);
  402. X                modem->no_con4[j] = strdup(modem->no_con4[j+1]);
  403. X            }
  404. X            j = modem->m_entries -1;
  405. X
  406. X            free_ptr(modem->mname[j]);
  407. X            free_ptr(modem->init[j]);
  408. X            free_ptr(modem->dial[j]);
  409. X            free_ptr(modem->suffix[j]);
  410. X            free_ptr(modem->hang_up[j]);
  411. X
  412. X            free_ptr(modem->con_3[j]);
  413. X            free_ptr(modem->con_12[j]);
  414. X            free_ptr(modem->con_24[j]);
  415. X            free_ptr(modem->con_48[j]);
  416. X            free_ptr(modem->con_96[j]);
  417. X            free_ptr(modem->con_192[j]);
  418. X
  419. X            free_ptr(modem->no_con1[j]);
  420. X            free_ptr(modem->no_con2[j]);
  421. X            free_ptr(modem->no_con3[j]);
  422. X            free_ptr(modem->no_con4[j]);
  423. X
  424. X                    /* create an empty entry */
  425. X            modem->mname[j] = null_ptr;
  426. X            modem->init[j] = null_ptr;
  427. X            modem->dial[j] = null_ptr;
  428. X            modem->suffix[j] = null_ptr;
  429. X            modem->hang_up[j] = null_ptr;
  430. X
  431. X            modem->auto_baud[j] = 'Y';
  432. X            modem->con_3[j] = null_ptr;
  433. X            modem->con_12[j] = null_ptr;
  434. X            modem->con_24[j] = null_ptr;
  435. X            modem->con_48[j] = null_ptr;
  436. X            modem->con_96[j] = null_ptr;
  437. X            modem->con_192[j] = null_ptr;
  438. X
  439. X            modem->no_con1[j] = null_ptr;
  440. X            modem->no_con2[j] = null_ptr;
  441. X            modem->no_con3[j] = null_ptr;
  442. X            modem->no_con4[j] = null_ptr;
  443. X
  444. X                    /* update the counts */
  445. X            modem->m_entries--;
  446. X            if (modem->m_cur >= modem->m_entries)
  447. X                modem->m_cur = -1;
  448. X            return;
  449. X        }
  450. X    }
  451. X    return;
  452. X}
  453. SHAR_EOF
  454. if test 10070 -ne "`wc -c < 'm_lib.c'`"
  455. then
  456.     echo shar: "error transmitting 'm_lib.c'" '(should have been 10070 characters)'
  457. fi
  458. fi
  459. echo shar: "extracting 'macro.c'" '(5243 characters)'
  460. if test -f 'macro.c'
  461. then
  462.     echo shar: "will not over-write existing file 'macro.c'"
  463. else
  464. sed 's/^X//' << \SHAR_EOF > 'macro.c'
  465. X/*
  466. X * The keyboard macro feature.  Displays (and prompts for editing) the
  467. X * macros assigned to the shifted number keys.  Prompts for saving
  468. X * changes to disk.
  469. X */
  470. X
  471. X#include <stdio.h>
  472. X#include <curses.h>
  473. X#include "config.h"
  474. X#include "misc.h"
  475. X#include "param.h"
  476. X
  477. Xint
  478. Xmacro()
  479. X{
  480. X    extern int fd;
  481. X    WINDOW *ma_win, *newwin();
  482. X    int ans, ret_code;
  483. X    char *mac, *strdup(), *mac_prompt();
  484. X    void free_ptr();
  485. X
  486. X    ma_win = newwin(18, 65, 2, 15);
  487. X    mvwattrstr(ma_win, 1, 25, A_BOLD, "Keyboard Macros");
  488. X    horizontal(ma_win, 2, 0, 65);
  489. X    mvwprintw(ma_win, 4, 0, " %4.4s-!  %-50.50s\n", param->ascii_hot, param->mac_1);
  490. X    wprintw(ma_win, " %4.4s-@  %-50.50s\n", param->ascii_hot, param->mac_2);
  491. X    wprintw(ma_win, " %4.4s-#  %-50.50s\n", param->ascii_hot, param->mac_3);
  492. X    wprintw(ma_win, " %4.4s-$  %-50.50s\n", param->ascii_hot, param->mac_4);
  493. X    wprintw(ma_win, " %4.4s-%%  %-50.50s\n", param->ascii_hot, param->mac_5);
  494. X    wprintw(ma_win, " %4.4s-^  %-50.50s\n", param->ascii_hot, param->mac_6);
  495. X    wprintw(ma_win, " %4.4s-&  %-50.50s\n", param->ascii_hot, param->mac_7);
  496. X    wprintw(ma_win, " %4.4s-*  %-50.50s\n", param->ascii_hot, param->mac_8);
  497. X    wprintw(ma_win, " %4.4s-(  %-50.50s\n", param->ascii_hot, param->mac_9);
  498. X    wprintw(ma_win, " %4.4s-)  %-50.50s\n", param->ascii_hot, param->mac_0);
  499. X    mvwaddstr(ma_win, 15, 5, "Macro key to revise:");
  500. X    box(ma_win, VERT, HORZ);
  501. X                    /* on the bottom line */
  502. X    mvwaddstr(ma_win, 17, 21, " Press <ESC> to continue ");
  503. X    wmove(ma_win, 15, 26);
  504. X    wrefresh(ma_win);
  505. X
  506. X    ret_code = 0;
  507. X
  508. X    while ((ans = wgetch(ma_win)) != ESC) {
  509. X        switch (ans) {
  510. X            case '!':    /* shifted 1 */
  511. X                if ((mac = mac_prompt(ans, param->mac_1)) != NULL) {
  512. X                    free_ptr(param->mac_1);
  513. X                    param->mac_1 = strdup(mac);
  514. X                    clear_line(ma_win, 4, 9, 1);
  515. X                    mvwattrstr(ma_win, 4, 9, A_BOLD, mac);
  516. X                    ret_code++;
  517. X                }
  518. X                break;
  519. X            case '@':    /* shifted 2 */
  520. X                if ((mac = mac_prompt(ans, param->mac_2)) != NULL) {
  521. X                    free_ptr(param->mac_2);
  522. X                    param->mac_2 = strdup(mac);
  523. X                    clear_line(ma_win, 5, 9, 1);
  524. X                    mvwattrstr(ma_win, 5, 9, A_BOLD, mac);
  525. X                    ret_code++;
  526. X                }
  527. X                break;
  528. X            case '#':    /* shifted 3 */
  529. X                if ((mac = mac_prompt(ans, param->mac_3)) != NULL) {
  530. X                    free_ptr(param->mac_3);
  531. X                    param->mac_3 = strdup(mac);
  532. X                    clear_line(ma_win, 6, 9, 1);
  533. X                    mvwattrstr(ma_win, 6, 9, A_BOLD, mac);
  534. X                    ret_code++;
  535. X                }
  536. X                break;
  537. X            case '$':    /* shifted 4 */
  538. X                if ((mac = mac_prompt(ans, param->mac_4)) != NULL) {
  539. X                    free_ptr(param->mac_4);
  540. X                    param->mac_4 = strdup(mac);
  541. X                    clear_line(ma_win, 7, 9, 1);
  542. X                    mvwattrstr(ma_win, 7, 9, A_BOLD, mac);
  543. X                    ret_code++;
  544. X                }
  545. X                break;
  546. X            case '%':    /* shifted 5 */
  547. X                if ((mac = mac_prompt(ans, param->mac_5)) != NULL) {
  548. X                    free_ptr(param->mac_5);
  549. X                    param->mac_5 = strdup(mac);
  550. X                    clear_line(ma_win, 8, 9, 1);
  551. X                    mvwattrstr(ma_win, 8, 9, A_BOLD, mac);
  552. X                    ret_code++;
  553. X                }
  554. X                break;
  555. X            case '^':    /* shifted 6 */
  556. X                if ((mac = mac_prompt(ans, param->mac_6)) != NULL) {
  557. X                    free_ptr(param->mac_6);
  558. X                    param->mac_6 = strdup(mac);
  559. X                    clear_line(ma_win, 9, 9, 1);
  560. X                    mvwattrstr(ma_win, 9, 9, A_BOLD, mac);
  561. X                    ret_code++;
  562. X                }
  563. X                break;
  564. X            case '&':    /* shifted 7 */
  565. X                if ((mac = mac_prompt(ans, param->mac_7)) != NULL) {
  566. X                    free_ptr(param->mac_7);
  567. X                    param->mac_7 = strdup(mac);
  568. X                    clear_line(ma_win, 10, 9, 1);
  569. X                    mvwattrstr(ma_win, 10, 9, A_BOLD, mac);
  570. X                    ret_code++;
  571. X                }
  572. X                break;
  573. X            case '*':    /* shifted 8 */
  574. X                if ((mac = mac_prompt(ans, param->mac_8)) != NULL) {
  575. X                    free_ptr(param->mac_8);
  576. X                    param->mac_8 = strdup(mac);
  577. X                    clear_line(ma_win, 11, 9, 1);
  578. X                    mvwattrstr(ma_win, 11, 9, A_BOLD, mac);
  579. X                    ret_code++;
  580. X                }
  581. X                break;
  582. X            case '(':    /* shifted 9 */
  583. X                if ((mac = mac_prompt(ans, param->mac_9)) != NULL) {
  584. X                    free_ptr(param->mac_9);
  585. X                    param->mac_9 = strdup(mac);
  586. X                    clear_line(ma_win, 12, 9, 1);
  587. X                    mvwattrstr(ma_win, 12, 9, A_BOLD, mac);
  588. X                    ret_code++;
  589. X                }
  590. X                break;
  591. X            case ')':    /* shifted 0 */
  592. X                if ((mac = mac_prompt(ans, param->mac_0)) != NULL) {
  593. X                    free_ptr(param->mac_0);
  594. X                    param->mac_0 = strdup(mac);
  595. X                    clear_line(ma_win, 13, 9, 1);
  596. X                    mvwattrstr(ma_win, 13, 9, A_BOLD, mac);
  597. X                    ret_code++;
  598. X                }
  599. X                break;
  600. X            default:
  601. X                beep();
  602. X                break;
  603. X        }
  604. X        touchwin(ma_win);
  605. X        wmove(ma_win, 15, 26);
  606. X        wrefresh(ma_win);
  607. X    }
  608. X                    /* if something changed */
  609. X    if (ret_code) {
  610. X                    /* save to disk? */
  611. X        if (yes_prompt(ma_win, 15, 30, A_BOLD, "Save to disk")) {
  612. X            if (up_param()) {
  613. X                touchwin(ma_win);
  614. X                wrefresh(ma_win);
  615. X            }
  616. X        }
  617. X    }
  618. X    if (fd == -1) {
  619. X        werase(ma_win);
  620. X        wrefresh(ma_win);
  621. X    }
  622. X    delwin(ma_win);
  623. X    return(ret_code);
  624. X}
  625. X
  626. X/*
  627. X * Sounds like Mac Donalds doesn't it?  Actually, it opens a new window
  628. X * and prompts for the new macro.  Returns a pointer to the new string.
  629. X */
  630. X
  631. Xstatic char *
  632. Xmac_prompt(key, string)
  633. Xchar key, *string;
  634. X{
  635. X    extern char *null_ptr;
  636. X    WINDOW *mp_win, *newwin();
  637. X    char *new, *get_str();
  638. X
  639. X    mp_win = newwin(6, 65, 8, 0);
  640. X    mvwprintw(mp_win, 2, 3, "%4.4s-%c  %-50.50s", param->ascii_hot, key, string);
  641. X    mvwaddstr(mp_win, 3, 5, "New : ");
  642. X    box(mp_win, VERT, HORZ);
  643. X    wrefresh(mp_win);
  644. X
  645. X    new = get_str(mp_win, 50, "", "");
  646. X                    /* if space, change to NULL pointer */
  647. X    if (!strcmp(new, " "))
  648. X        new = null_ptr;
  649. X
  650. X    werase(mp_win);
  651. X    wrefresh(mp_win);
  652. X    delwin(mp_win);
  653. X    return(new);
  654. X}
  655. SHAR_EOF
  656. if test 5243 -ne "`wc -c < 'macro.c'`"
  657. then
  658.     echo shar: "error transmitting 'macro.c'" '(should have been 5243 characters)'
  659. fi
  660. fi
  661. echo shar: "extracting 'main.c'" '(6133 characters)'
  662. if test -f 'main.c'
  663. then
  664.     echo shar: "will not over-write existing file 'main.c'"
  665. else
  666. sed 's/^X//' << \SHAR_EOF > 'main.c'
  667. X/*
  668. X * Pcomm is a public domain telecommunication program for Unix that
  669. X * is designed to operate similar to the MSDOS program, ProComm.
  670. X * ProComm (TM) is copyrighted by Datastorm Technologies, Inc.
  671. X *
  672. X * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  673. X * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  674. X *                    Directorate of Engineering & Housing
  675. X *                    Environmental Management Office
  676. X *                    Fort Hood, TX 76544-5057
  677. X *
  678. X *    Release v1.0    12 Mar 88
  679. X *      patch #1    22 Mar 88
  680. X *      patch #2    26 Mar 88
  681. X *      patch #3     3 Apr 88
  682. X *      patch #4    14 Apr 88
  683. X *      patch #5    25 May 88
  684. X *    Release v1.1    21 Aug 88
  685. X */
  686. X
  687. X#include <stdio.h>
  688. X#include <signal.h>
  689. X#include <curses.h>
  690. X#include <sys/types.h>
  691. X#include <sys/stat.h>
  692. X#include "config.h"
  693. X#ifndef OLDCURSES
  694. X#include <term.h>
  695. X#endif /* OLDCURSES */
  696. X#define MAIN
  697. X#include "dial_dir.h"
  698. X#include "modem.h"
  699. X#include "param.h"
  700. X#include "status.h"
  701. X
  702. X#ifdef OLDCURSES
  703. Xchar tcbuf[1024], *TI, *VS;
  704. X#define cbreak crmode
  705. X#endif /* OLDCURSES */
  706. X
  707. X#ifdef SHAREDMEM
  708. Xint shm_id;
  709. X#endif /* SHAREDMEM */
  710. X
  711. Xstruct PARAM *param;
  712. Xstruct DIAL_DIR *dir;
  713. Xstruct STATUS *status;
  714. Xstruct MODEM *modem;
  715. X
  716. Xint fd = -1;                /* file descriptor for port */
  717. Xint xmc;                /* magic cookie terminal */
  718. Xint msg_status;                /* read/write permissions on TTY */
  719. Xchar *null_ptr = "";            /* generic null pointer */
  720. X
  721. Xmain(argc, argv)
  722. Xint argc;
  723. Xchar *argv[];
  724. X{
  725. X    extern char *optarg;
  726. X    int c, ret_code, i, code, quit();
  727. X    char *mytty, *ttyname(), *term, *getenv(), *short_cut, *strdup();
  728. X    char *extra_dir, buf[80], message[80];
  729. X    struct PARAM *read_param();
  730. X    struct DIAL_DIR *read_dir();
  731. X    struct STATUS *init();
  732. X    struct MODEM *read_modem();
  733. X    struct stat stbuf;
  734. X    void exit(), error_win(), free_ptr();
  735. X#ifdef OLDCURSES
  736. X    char *tgetstr(), *t, tb[1024];
  737. X    t = tcbuf;
  738. X#endif /* OLDCURSES */
  739. X
  740. X    signal(SIGINT, SIG_IGN);
  741. X    signal(SIGQUIT, SIG_IGN);
  742. X    signal(SIGTERM, quit);
  743. X    signal(SIGHUP, quit);
  744. X
  745. X    short_cut = NULL;
  746. X    extra_dir = NULL;
  747. X                    /* the command line */
  748. X    while ((c = getopt(argc, argv, "d:f:")) != EOF) {
  749. X        switch (c) {
  750. X            case 'd':    /* the extra directory to search */
  751. X                extra_dir = strdup(optarg);
  752. X                break;
  753. X            case 'f':    /* the index into the dialing dir */
  754. X                short_cut = strdup(optarg);
  755. X                break;
  756. X            case '?':    /* default */
  757. X                fprintf(stderr, "Usage: pcomm [-d directory] [-f index]\n");
  758. X                exit(1);
  759. X                break;
  760. X        }
  761. X    }
  762. X                    /* get terminal type */
  763. X    term = getenv("TERM");
  764. X    if (term == NULL || *term == NULL) {
  765. X        fprintf(stderr, "Windows not supported (TERM not defined)\n");
  766. X        exit(1);
  767. X    }
  768. X                    /* see if terminfo entry exists */
  769. X#ifdef OLDCURSES
  770. X    ret_code = tgetent(tb, term);
  771. X#else /* OLDCURSES */
  772. X    setupterm(term, 1, &ret_code);
  773. X#endif /* OLDCURSES */
  774. X    if (ret_code != 1) {
  775. X        fprintf(stderr, "Windows not supported (no terminfo data for '%s')\n", term);
  776. X        exit(1);
  777. X    }
  778. X                    /* minimum screen size */
  779. X#ifdef OLDCURSES
  780. X    if (tgetnum("co") < 80 || tgetnum("li") < 24) {
  781. X#else /* OLDCURSES */
  782. X    if (columns < 80 || lines < 24) {
  783. X#endif /* OLDCURSES */
  784. X        fprintf(stderr, "Windows not supported (minimum 80x24 screen required)\n");
  785. X        exit(1);
  786. X    }
  787. X                    /* must have cursor movement */
  788. X#ifdef OLDCURSES
  789. X    if (tgetstr("cm", &t) == NULL) {
  790. X#else /* OLDCURSES */
  791. X    if (cursor_address == NULL) {
  792. X#endif /* OLDCURSES */
  793. X        fprintf(stderr, "Windows not supported (terminal too dumb)\n");
  794. X        exit(1);
  795. X    }
  796. X                    /* load magic cookie variable */
  797. X#ifdef OLDCURSES
  798. X    xmc = tgetnum("sg");
  799. X    TI = tgetstr("ti", &t);
  800. X    VS = tgetstr("vs", &t);
  801. X#else /* OLDCURSES */
  802. X    xmc = magic_cookie_glitch;
  803. X#endif /* OLDCURSES */
  804. X                    /* ok... now lets go! */
  805. X    initscr();
  806. X    nonl();
  807. X    cbreak();
  808. X    noecho();
  809. X
  810. X    param = (struct PARAM *) NULL;
  811. X    modem = (struct MODEM *) NULL;
  812. X    dir = (struct DIAL_DIR *) NULL;
  813. X                    /* show the herald, return status */
  814. X    status = init(short_cut);
  815. X                    /* get "msgs" status */
  816. X    mytty = ttyname(0);
  817. X    stat(mytty, &stbuf);
  818. X    chmod(mytty, 0600);
  819. X    msg_status = stbuf.st_mode & 0777;
  820. X                    /* read the support files */
  821. X    param = read_param(extra_dir);
  822. X    dir = read_dir(extra_dir);
  823. X    modem = read_modem(extra_dir);
  824. X    free_ptr(extra_dir);
  825. X                    /* warning about screen size */
  826. X    if (LINES > MAX_ROW || COLS > MAX_COL)
  827. X        error_win(0, "Your screen size exceeds an internal Pcomm limit",
  828. X         "The edges of the screen may contain garbage");
  829. X
  830. X                    /* short-cut to dialing window? */
  831. X    code = 0;
  832. X    if (short_cut != NULL) {
  833. X        for (i=1; i<dir->d_entries+1; i++) {
  834. X            if (!strcmp(dir->index[i], short_cut)) {
  835. X                dir->q_num[0] = i;
  836. X                dir->d_cur = i;
  837. X                break;
  838. X            }
  839. X        }
  840. X                    /* if match is found */
  841. X        if (dir->q_num[0] != -1)
  842. X            code = dial_win();
  843. X        else {
  844. X            sprintf(buf, "Can't find index '%s' in dialing directory", short_cut);
  845. X            sprintf(message, "file '%s'", dir->d_path);
  846. X            error_win(0, buf, message);
  847. X        }
  848. X        free_ptr(short_cut);
  849. X    }
  850. X                    /* start terminal dialogue */
  851. X    terminal(code);
  852. X    exit(0);
  853. X}
  854. X
  855. X/*
  856. X * Something dreadful happened...  Clean up the mess we made with the
  857. X * TTY driver and release the phone line.
  858. X */
  859. X
  860. Xint
  861. Xquit()
  862. X{
  863. X    void cleanup();
  864. X
  865. X    cleanup(1);
  866. X                    /* never returns... */
  867. X    return(0);
  868. X}
  869. X
  870. X/*
  871. X * Check write permission with the real UID and GID.  Returns a 0 on
  872. X * permission denied, 1 on OK, and 2 on OK-but the file already exists.
  873. X */
  874. X
  875. Xint
  876. Xcan_write(file)
  877. Xchar *file;
  878. X{
  879. X    char *p, path[200], *strcpy(), *strrchr();
  880. X
  881. X    p = strcpy(path, file);
  882. X                    /* dissect the path component */
  883. X    if (p = strrchr(path, '/'))
  884. X        *(p++) = NULL;
  885. X    else
  886. X        strcpy(path, ".");
  887. X                    /* if it already exists */
  888. X    if (!access(file, 0)) {
  889. X        if (!access(file, 2))
  890. X            return(2);
  891. X        return(0);
  892. X    }
  893. X                    /* if path is writable */
  894. X    if (!access(path, 2))
  895. X        return(1);
  896. X    return(0);
  897. X}
  898. X
  899. X/*
  900. X * Check the read and write permissions before opening a file.  This
  901. X * is a horrible kludge to work around that fact that a lot of systems
  902. X * that claim to be SVID compatible don't treat setuid(2) and setgid(2)
  903. X * properly.  For example, on a Masscomp, you can't flip-flop back and
  904. X * forth between the real and effective UID/GID.
  905. X */
  906. X
  907. XFILE *
  908. Xmy_fopen(file, mode)
  909. Xchar *file, *mode;
  910. X{
  911. X#ifdef SETUGID
  912. X    switch (*mode) {
  913. X        case 'a':
  914. X        case 'w':
  915. X            if (!can_write(file))
  916. X                return(NULL);
  917. X            break;
  918. X        case 'r':
  919. X            if (access(file, 4))
  920. X                return(NULL);
  921. X            break;
  922. X    }
  923. X#endif /* SETUGID */
  924. X    return ((FILE *) fopen(file, mode));
  925. X}
  926. SHAR_EOF
  927. if test 6133 -ne "`wc -c < 'main.c'`"
  928. then
  929.     echo shar: "error transmitting 'main.c'" '(should have been 6133 characters)'
  930. fi
  931. fi
  932. echo shar: "extracting 'n_shell.c'" '(1255 characters)'
  933. if test -f 'n_shell.c'
  934. then
  935.     echo shar: "will not over-write existing file 'n_shell.c'"
  936. else
  937. sed 's/^X//' << \SHAR_EOF > 'n_shell.c'
  938. X/*
  939. X * Spawn a "native" shell.  Native means the shell found in the SHELL
  940. X * environmental variable.
  941. X */
  942. X
  943. X#include <stdio.h>
  944. X#include <signal.h>
  945. X#include <curses.h>
  946. X#include "config.h"
  947. X
  948. Xvoid
  949. Xn_shell()
  950. X{
  951. X    WINDOW *sh_win, *newwin();
  952. X    int (*istat)(), (*qstat)(), status, spid, w;
  953. X    char *shell, *shellpath, *getenv(), *strrchr();
  954. X    unsigned int sleep();
  955. X    void _exit();
  956. X                    /* a full window */
  957. X    sh_win = newwin(LINES, COLS, 0, 0);
  958. X
  959. X    touchwin(sh_win);
  960. X    waddstr(sh_win, "Pcomm <=> Unix gateway, use ^D or 'exit' to return\n");
  961. X    wrefresh(sh_win);
  962. X                    /* out of curses mode */
  963. X    resetterm();
  964. X
  965. X    shellpath = getenv("SHELL");
  966. X    if (shellpath == NULL || *shellpath == NULL)
  967. X        shellpath = "/bin/sh";
  968. X
  969. X    shell = strrchr(shellpath, '/') + 1;
  970. X
  971. X    if (!(spid = fork())) {
  972. X        signal(SIGINT, SIG_DFL);
  973. X        signal(SIGQUIT, SIG_DFL);
  974. X#ifdef SETUGID
  975. X        setgid(getgid());
  976. X        setuid(getuid());
  977. X#endif /* SETUGID */
  978. X        execl(shellpath, shell, "-i", (char *) 0);
  979. X        _exit(1);
  980. X    }
  981. X    istat = signal(SIGINT, SIG_IGN);
  982. X    qstat = signal(SIGQUIT, SIG_IGN);
  983. X
  984. X    while ((w = wait(&status)) != spid && w != -1)
  985. X        ;
  986. X
  987. X    signal(SIGINT, istat);
  988. X    signal(SIGQUIT, qstat);
  989. X                    /* back to curses mode */
  990. X    sleep(1);
  991. X    fixterm();
  992. X
  993. X    clearok(curscr, TRUE);
  994. X    werase(sh_win);
  995. X    wrefresh(sh_win);
  996. X    delwin(sh_win);
  997. X    return;
  998. X}
  999. SHAR_EOF
  1000. if test 1255 -ne "`wc -c < 'n_shell.c'`"
  1001. then
  1002.     echo shar: "error transmitting 'n_shell.c'" '(should have been 1255 characters)'
  1003. fi
  1004. fi
  1005. echo shar: "extracting 'p_lib.c'" '(7151 characters)'
  1006. if test -f 'p_lib.c'
  1007. then
  1008.     echo shar: "will not over-write existing file 'p_lib.c'"
  1009. else
  1010. sed 's/^X//' << \SHAR_EOF > 'p_lib.c'
  1011. X/*
  1012. X * Routines to manipulate the pcomm.param file.
  1013. X */
  1014. X
  1015. X#include <stdio.h>
  1016. X#include "param.h"
  1017. X
  1018. X/*
  1019. X * Read the parameter structure from the pcomm.param file.  Returns a
  1020. X * pointer to the PARAM structure.  All errors are fatal.
  1021. X */
  1022. X
  1023. Xstruct PARAM *
  1024. Xread_param(extra)
  1025. Xchar *extra;
  1026. X{
  1027. X    FILE *fp;
  1028. X    int i, oops;
  1029. X    char buf[80], *temp_token, *str, *strdup(), *findfile();
  1030. X    char message[80], *str_tok();
  1031. X    static char *token[NUM_PARAM] = {"D_BAUD", "D_PARITY", "D_DBITS",
  1032. X    "D_SBITS", "HOT", "ASCII_HOT", "D_DUPLEX", "FLOW", "CR_IN", "CR_OUT",
  1033. X    "LOGFILE", "DUMPFILE", "STRIP", "PAUSE_CHAR", "CR_CHAR", "CTRL_CHAR",
  1034. X    "ESC_CHAR", "BRK_CHAR", "ABORT", "C_DELAY", "R_DELAY", "LECHO",
  1035. X    "EXPAND", "CR_DELAY", "PACE", "CR_UP", "LF_UP", "TIMER", "CR_DN",
  1036. X    "LF_DN", "LD_PLUS", "LD_MINUS", "LD_AT", "LD_POUND", "MAC_1",
  1037. X    "MAC_2", "MAC_3", "MAC_4", "MAC_5", "MAC_6", "MAC_7", "MAC_8",
  1038. X    "MAC_9", "MAC_0"};
  1039. X    static struct PARAM p;
  1040. X    void error_win();
  1041. X
  1042. X    if ((p.p_path = findfile(extra, "pcomm.param")) == NULL)
  1043. X        error_win(1, "Support file 'pcomm.param' is missing", "or no read permission");
  1044. X                    /* read permission already checked */
  1045. X    fp = fopen(p.p_path, "r");
  1046. X
  1047. X    oops = 0;
  1048. X    for (i=0; i<NUM_PARAM; i++) {
  1049. X        if (fgets(buf, 80, fp) == NULL) {
  1050. X            sprintf(message, "is truncated at line %d", i+1);
  1051. X            oops++;
  1052. X            break;
  1053. X        }
  1054. X                    /* parse the input line */
  1055. X        if (!(temp_token = str_tok(buf, '='))) {
  1056. X            sprintf(message, "is missing a token at line %d", i+1);
  1057. X            oops++;
  1058. X            break;
  1059. X        }
  1060. X        if (!(str = str_tok((char *) NULL, '\n'))) {
  1061. X            sprintf(message, "is missing a parameter at line %d", i+1);
  1062. X            oops++;
  1063. X            break;
  1064. X        }
  1065. X                    /* sanity checking */
  1066. X        if (strcmp(temp_token, token[i])) {
  1067. X            sprintf(message, "is corrupted at line %d", i+1);
  1068. X            oops++;
  1069. X            break;
  1070. X        }
  1071. X
  1072. X        switch (i) {
  1073. X                    /* used in ls_menu() */
  1074. X            case LINE_SET:
  1075. X                p.d_baud = atoi(str);
  1076. X                break;
  1077. X            case LINE_SET+1:
  1078. X                p.d_parity = *str;
  1079. X                break;
  1080. X            case LINE_SET+2:
  1081. X                p.d_dbits = atoi(str);
  1082. X                break;
  1083. X            case LINE_SET+3:
  1084. X                p.d_sbits = atoi(str);
  1085. X                break;
  1086. X
  1087. X                    /* used in term_setup() */
  1088. X            case TERM_SETUP:
  1089. X                p.hot = atoi(str);
  1090. X                break;
  1091. X            case TERM_SETUP+1:
  1092. X                p.ascii_hot = strdup(str);
  1093. X                break;
  1094. X            case TERM_SETUP+2:
  1095. X                p.d_duplex = strdup(str);
  1096. X                break;
  1097. X            case TERM_SETUP+3:
  1098. X                p.flow = strdup(str);
  1099. X                break;
  1100. X            case TERM_SETUP+4:
  1101. X                p.cr_in = strdup(str);
  1102. X                break;
  1103. X            case TERM_SETUP+5:
  1104. X                p.cr_out = strdup(str);
  1105. X                break;
  1106. X
  1107. X                    /* used in gen_setup() */
  1108. X            case GEN_SETUP:
  1109. X                p.logfile = strdup(str);
  1110. X                break;
  1111. X            case GEN_SETUP+1:
  1112. X                p.dumpfile = strdup(str);
  1113. X                break;
  1114. X            case GEN_SETUP+2:
  1115. X                p.strip = strdup(str);
  1116. X                break;
  1117. X            case GEN_SETUP+3:
  1118. X                p.pause_char = *str;
  1119. X                break;
  1120. X            case GEN_SETUP+4:
  1121. X                p.cr_char = *str;
  1122. X                break;
  1123. X            case GEN_SETUP+5:
  1124. X                p.ctrl_char = *str;
  1125. X                break;
  1126. X            case GEN_SETUP+6:
  1127. X                p.esc_char = *str;
  1128. X                break;
  1129. X            case GEN_SETUP+7:
  1130. X                p.brk_char = *str;
  1131. X                break;
  1132. X            case GEN_SETUP+8:
  1133. X                p.abort = strdup(str);
  1134. X                break;
  1135. X
  1136. X                    /* used in gen_setup() delay_times() */
  1137. X            case DELAY_TIMES:
  1138. X                p.c_delay = atoi(str);
  1139. X                break;
  1140. X            case DELAY_TIMES+1:
  1141. X                p.r_delay = atoi(str);
  1142. X                break;
  1143. X
  1144. X                    /* used in axfer_setup() */
  1145. X            case ASCII_SETUP:
  1146. X                p.lecho = strdup(str);
  1147. X                break;
  1148. X            case ASCII_SETUP+1:
  1149. X                p.expand = strdup(str);
  1150. X                break;
  1151. X            case ASCII_SETUP+2:
  1152. X                p.cr_delay = atoi(str);
  1153. X                break;
  1154. X            case ASCII_SETUP+3:
  1155. X                p.pace = strdup(str);
  1156. X                break;
  1157. X            case ASCII_SETUP+4:
  1158. X                p.cr_up = strdup(str);
  1159. X                break;
  1160. X            case ASCII_SETUP+5:
  1161. X                p.lf_up = strdup(str);
  1162. X                break;
  1163. X            case ASCII_SETUP+6:
  1164. X                p.timer = atoi(str);
  1165. X                break;
  1166. X            case ASCII_SETUP+7:
  1167. X                p.cr_dn = strdup(str);
  1168. X                break;
  1169. X            case ASCII_SETUP+8:
  1170. X                p.lf_dn = strdup(str);
  1171. X                break;
  1172. X
  1173. X                    /* used in d_revise() */
  1174. X            case LD_CODES:
  1175. X                p.ld_plus = strdup(str);
  1176. X                break;
  1177. X            case LD_CODES+1:
  1178. X                p.ld_minus = strdup(str);
  1179. X                break;
  1180. X            case LD_CODES+2:
  1181. X                p.ld_at = strdup(str);
  1182. X                break;
  1183. X            case LD_CODES+3:
  1184. X                p.ld_pound = strdup(str);
  1185. X                break;
  1186. X
  1187. X                    /* used in macro() */
  1188. X            case MACROS:
  1189. X                p.mac_1 = strdup(str);
  1190. X                break;
  1191. X            case MACROS+1:
  1192. X                p.mac_2 = strdup(str);
  1193. X                break;
  1194. X            case MACROS+2:
  1195. X                p.mac_3 = strdup(str);
  1196. X                break;
  1197. X            case MACROS+3:
  1198. X                p.mac_4 = strdup(str);
  1199. X                break;
  1200. X            case MACROS+4:
  1201. X                p.mac_5 = strdup(str);
  1202. X                break;
  1203. X            case MACROS+5:
  1204. X                p.mac_6 = strdup(str);
  1205. X                break;
  1206. X            case MACROS+6:
  1207. X                p.mac_7 = strdup(str);
  1208. X                break;
  1209. X            case MACROS+7:
  1210. X                p.mac_8 = strdup(str);
  1211. X                break;
  1212. X            case MACROS+8:
  1213. X                p.mac_9 = strdup(str);
  1214. X                break;
  1215. X            case MACROS+9:
  1216. X                p.mac_0 = strdup(str);
  1217. X                break;
  1218. X        }
  1219. X    }
  1220. X    fclose(fp);
  1221. X    if (oops) {
  1222. X        sprintf(buf, "Parameter file '%s'", p.p_path);
  1223. X        error_win(1, buf, message);
  1224. X    }
  1225. X    return(&p);
  1226. X}
  1227. X
  1228. X/*
  1229. X * Write the updated param structure to disk.  The values in memory should
  1230. X * have already been "purified".  Later, we'll update only the entries that
  1231. X * have been explicitly asked for.  A return code of 1 means non-fatal error.
  1232. X */
  1233. X
  1234. Xint
  1235. Xup_param()
  1236. X{
  1237. X    FILE *fp, *my_fopen();
  1238. X    char buf[80];
  1239. X    void error_win();
  1240. X                    /* open for write */
  1241. X    if (!(fp = my_fopen(param->p_path, "w"))) {
  1242. X        sprintf(buf, "'%s'", param->p_path);
  1243. X        error_win(0, "No write permission on parameter file", buf);
  1244. X        return(1);
  1245. X    }
  1246. X
  1247. X    fprintf(fp, "D_BAUD=%d\n", param->d_baud);
  1248. X    fprintf(fp, "D_PARITY=%c\n", param->d_parity);
  1249. X    fprintf(fp, "D_DBITS=%d\n", param->d_dbits);
  1250. X    fprintf(fp, "D_SBITS=%d\n", param->d_sbits);
  1251. X    fprintf(fp, "HOT=%d\n", param->hot);
  1252. X    fprintf(fp, "ASCII_HOT=%s\n", param->ascii_hot);
  1253. X    fprintf(fp, "D_DUPLEX=%s\n", param->d_duplex);
  1254. X    fprintf(fp, "FLOW=%s\n", param->flow);
  1255. X    fprintf(fp, "CR_IN=%s\n", param->cr_in);
  1256. X    fprintf(fp, "CR_OUT=%s\n", param->cr_out);
  1257. X    fprintf(fp, "LOGFILE=%s\n", param->logfile);
  1258. X    fprintf(fp, "DUMPFILE=%s\n", param->dumpfile);
  1259. X    fprintf(fp, "STRIP=%s\n", param->strip);
  1260. X    fprintf(fp, "PAUSE_CHAR=%c\n", param->pause_char);
  1261. X    fprintf(fp, "CR_CHAR=%c\n", param->cr_char);
  1262. X    fprintf(fp, "CTRL_CHAR=%c\n", param->ctrl_char);
  1263. X    fprintf(fp, "ESC_CHAR=%c\n", param->esc_char);
  1264. X    fprintf(fp, "BRK_CHAR=%c\n", param->brk_char);
  1265. X    fprintf(fp, "ABORT=%s\n", param->abort);
  1266. X    fprintf(fp, "C_DELAY=%d\n", param->c_delay);
  1267. X    fprintf(fp, "R_DELAY=%d\n", param->r_delay);
  1268. X    fprintf(fp, "LECHO=%s\n", param->lecho);
  1269. X    fprintf(fp, "EXPAND=%s\n", param->expand);
  1270. X    fprintf(fp, "CR_DELAY=%d\n", param->cr_delay);
  1271. X    fprintf(fp, "PACE=%s\n", param->pace);
  1272. X    fprintf(fp, "CR_UP=%s\n", param->cr_up);
  1273. X    fprintf(fp, "LF_UP=%s\n", param->lf_up);
  1274. X    fprintf(fp, "TIMER=%d\n", param->timer);
  1275. X    fprintf(fp, "CR_DN=%s\n", param->cr_dn);
  1276. X    fprintf(fp, "LF_DN=%s\n", param->lf_dn);
  1277. X    fprintf(fp, "LD_PLUS=%s\n", param->ld_plus);
  1278. X    fprintf(fp, "LD_MINUS=%s\n", param->ld_minus);
  1279. X    fprintf(fp, "LD_AT=%s\n", param->ld_at);
  1280. X    fprintf(fp, "LD_POUND=%s\n", param->ld_pound);
  1281. X    fprintf(fp, "MAC_1=%s\n", param->mac_1);
  1282. X    fprintf(fp, "MAC_2=%s\n", param->mac_2);
  1283. X    fprintf(fp, "MAC_3=%s\n", param->mac_3);
  1284. X    fprintf(fp, "MAC_4=%s\n", param->mac_4);
  1285. X    fprintf(fp, "MAC_5=%s\n", param->mac_5);
  1286. X    fprintf(fp, "MAC_6=%s\n", param->mac_6);
  1287. X    fprintf(fp, "MAC_7=%s\n", param->mac_7);
  1288. X    fprintf(fp, "MAC_8=%s\n", param->mac_8);
  1289. X    fprintf(fp, "MAC_9=%s\n", param->mac_9);
  1290. X    fprintf(fp, "MAC_0=%s\n", param->mac_0);
  1291. X
  1292. X    fclose(fp);
  1293. X    return(0);
  1294. X}
  1295. SHAR_EOF
  1296. if test 7151 -ne "`wc -c < 'p_lib.c'`"
  1297. then
  1298.     echo shar: "error transmitting 'p_lib.c'" '(should have been 7151 characters)'
  1299. fi
  1300. fi
  1301. echo shar: "extracting 'passthru.c'" '(2141 characters)'
  1302. if test -f 'passthru.c'
  1303. then
  1304.     echo shar: "will not over-write existing file 'passthru.c'"
  1305. else
  1306. sed 's/^X//' << \SHAR_EOF > 'passthru.c'
  1307. X/*
  1308. X * A transparent "pass-thru" mode, designed to allow binary transfers
  1309. X * between 3 machines (with the middle machine in the pass-thru mode).
  1310. X * A non-zero return code means the input routine should be restarted.
  1311. X */
  1312. X
  1313. X#include <stdio.h>
  1314. X#include <signal.h>
  1315. X#include <curses.h>
  1316. X#include "config.h"
  1317. X#include "misc.h"
  1318. X
  1319. Xint
  1320. Xpass_thru()
  1321. X{
  1322. X    extern int fd;
  1323. X    WINDOW *pt_win, *newwin();
  1324. X    int num;
  1325. X    void cpio();
  1326. X
  1327. X    pt_win = newwin(5, 70, 5, 5);
  1328. X
  1329. X    mvwaddstr(pt_win, 2, 4, "Enter the expiration time (5-60 sec): ");
  1330. X    box(pt_win, VERT, HORZ);
  1331. X
  1332. X    mvwattrstr(pt_win, 0, 3, A_BOLD, " Pass Through Mode ");
  1333. X    wmove(pt_win, 2, 43);
  1334. X    wrefresh(pt_win);
  1335. X                    /* get the answer */
  1336. X    while ((num = get_num(pt_win, 2)) != -1) {
  1337. X                    /* out of bounds */
  1338. X        if (num < 5 || num > 60) {
  1339. X            beep();
  1340. X            clear_line(pt_win, 2, 43, 1);
  1341. X            wmove(pt_win, 2, 43);
  1342. X            wrefresh(pt_win);
  1343. X        }
  1344. X        else {
  1345. X            werase(pt_win);
  1346. X            wrefresh(pt_win);
  1347. X            delwin(pt_win);
  1348. X
  1349. X            touchwin(stdscr);
  1350. X            refresh();
  1351. X
  1352. X            cpio((unsigned int) num);
  1353. X            return(1);
  1354. X        }
  1355. X    }
  1356. X    if (fd == -1) {
  1357. X        werase(pt_win);
  1358. X        wrefresh(pt_win);
  1359. X    }
  1360. X    delwin(pt_win);
  1361. X    return(0);
  1362. X}
  1363. X
  1364. X/*
  1365. X * Copy the stdin to the TTYout and copy the TTYin to the stdout.  Uses
  1366. X * multi character reads.  I'm not too concerned about the excess bagage
  1367. X * caused by the entire image being forked... this feature won't be used
  1368. X * that often.
  1369. X */
  1370. X
  1371. Xstatic int cp_flag;
  1372. X
  1373. Xstatic void
  1374. Xcpio(num)
  1375. Xunsigned int num;
  1376. X{
  1377. X    extern int fd;
  1378. X    int cpid, n, cp_force();
  1379. X    char buf[BUFSIZ];
  1380. X    unsigned int alarm(), sleep();
  1381. X    void line_set(), xmodem_mode(), input_off();
  1382. X
  1383. X                    /* out of curses mode */
  1384. X    resetterm();
  1385. X
  1386. X    input_off();
  1387. X    xmodem_mode(0);
  1388. X    xmodem_mode(fd);
  1389. X
  1390. X                    /* copy the TTYin to stdout */
  1391. X    if (!(cpid = fork())) {
  1392. X        while (1) {
  1393. X            n = read(fd, buf, BUFSIZ);
  1394. X            write(1, buf, n);
  1395. X        }
  1396. X    }
  1397. X
  1398. X    cp_flag = 0;
  1399. X    signal(SIGALRM, cp_force);
  1400. X                    /* copy the stdin to TTYout */
  1401. X    while (1) {
  1402. X        alarm(num);
  1403. X        n = read(0, buf, BUFSIZ);
  1404. X        if (cp_flag)
  1405. X            break;
  1406. X        write(fd, buf, n);
  1407. X    }
  1408. X    kill(cpid, SIGKILL);
  1409. X                    /* back to curses mode */
  1410. X    sleep(1);
  1411. X    fixterm();
  1412. X    beep();
  1413. X    line_set();
  1414. X    clearok(curscr, TRUE);
  1415. X    return;
  1416. X}
  1417. X/*ARGSUSED*/
  1418. Xstatic int
  1419. Xcp_force(dummy)
  1420. X{
  1421. X    cp_flag = 1;
  1422. X}
  1423. SHAR_EOF
  1424. if test 2141 -ne "`wc -c < 'passthru.c'`"
  1425. then
  1426.     echo shar: "error transmitting 'passthru.c'" '(should have been 2141 characters)'
  1427. fi
  1428. fi
  1429. echo shar: "extracting 'pexit.c'" '(2504 characters)'
  1430. if test -f 'pexit.c'
  1431. then
  1432.     echo shar: "will not over-write existing file 'pexit.c'"
  1433. else
  1434. sed 's/^X//' << \SHAR_EOF > 'pexit.c'
  1435. X/*
  1436. X * Exit Pcomm.  A user requested abort.  There are a lot of things to do
  1437. X * before we exit!
  1438. X */
  1439. X
  1440. X#include <stdio.h>
  1441. X#include <curses.h>
  1442. X#include "config.h"
  1443. X#ifdef SHAREDMEM
  1444. X#include <sys/types.h>
  1445. X#include <sys/ipc.h>
  1446. X#include <sys/shm.h>
  1447. X#endif /* SHAREDMEM */
  1448. X#include "dial_dir.h"
  1449. X#include "misc.h"
  1450. X#include "param.h"
  1451. X#include "status.h"
  1452. X
  1453. Xvoid
  1454. Xpexit()
  1455. X{
  1456. X    extern int fd;
  1457. X    WINDOW *ex_win, *newwin();
  1458. X    void cleanup(), st_line();
  1459. X
  1460. X    ex_win = newwin(5, 33, 3, 7);
  1461. X
  1462. X    box(ex_win, VERT, HORZ);
  1463. X    mvwattrstr(ex_win, 0, 3, A_BOLD, " Exit ");
  1464. X    if (yes_prompt(ex_win, 2, 4, A_BLINK, "Exit to Unix")) {
  1465. X        st_line("   exiting");
  1466. X        cleanup(0);
  1467. X    }
  1468. X    if (fd == -1) {
  1469. X        werase(ex_win);
  1470. X        wrefresh(ex_win);
  1471. X    }
  1472. X    delwin(ex_win);
  1473. X    return;
  1474. X}
  1475. X
  1476. X/*
  1477. X * Do the clean up detail before we exit.  Only the status structure
  1478. X * is guaranteed to exit.
  1479. X */
  1480. X
  1481. Xvoid
  1482. Xcleanup(val)
  1483. Xint val;
  1484. X{
  1485. X    extern int msg_status;
  1486. X    void release_port(), input_off(), exit();
  1487. X    char *ttyname();
  1488. X#ifdef SHAREDMEM
  1489. X    extern int shm_id;
  1490. X#endif /* SHAREDMEM */
  1491. X                    /* kill the input routine */
  1492. X    input_off();
  1493. X                    /* release the port */
  1494. X    release_port(0);
  1495. X                    /* zap the virtual screen */
  1496. X#ifdef SHAREDMEM
  1497. X    if (shmdt((char *) status) < 0)
  1498. X        perror("shmdt");
  1499. X    if (shmctl(shm_id, IPC_RMID, (struct shmid_ds *) NULL) < 0)
  1500. X        perror("shmctl");
  1501. X#else /* SHAREDMEM */
  1502. X    unlink(status->vs_path);
  1503. X#endif /* SHAREDMEM */
  1504. X
  1505. X    /*
  1506. X     * If we die an un-natural death (such as a SIGHUP on the loss of
  1507. X     * the controlling terminal) we won't have a terminal to mess with.
  1508. X     */
  1509. X    if (isatty(0)) {
  1510. X        touchwin(stdscr);
  1511. X        clear();
  1512. X        refresh();
  1513. X        endwin();
  1514. X                    /* return the TTY chmod */
  1515. X        chmod(ttyname(0), msg_status);
  1516. X    }
  1517. X    exit(val);
  1518. X}
  1519. X
  1520. X/*
  1521. X * Open a window to display an error message.  Handles both fatal and
  1522. X * non-fatal errors
  1523. X */
  1524. X
  1525. Xvoid
  1526. Xerror_win(code, line_one, line_two)
  1527. Xint code;
  1528. Xchar *line_one, *line_two;
  1529. X{
  1530. X    WINDOW *e_win, *newwin();
  1531. X    void cleanup(), st_line();
  1532. X
  1533. X    e_win = newwin(7, 70, 9, 5);
  1534. X                    /* display the nasty note */
  1535. X    mvwaddstr(e_win, 2, 4, line_one);
  1536. X    mvwaddstr(e_win, 3, 4, line_two);
  1537. X    box(e_win, VERT, HORZ);
  1538. X
  1539. X    if (code) {
  1540. X        mvwattrstr(e_win, 0, 4, A_BOLD, " Error ");
  1541. X        mvwattrstr(e_win, 5, 24, A_BLINK, "Press any key to exit");
  1542. X        wmove(e_win, 5, 46);
  1543. X    }
  1544. X    else {
  1545. X        mvwattrstr(e_win, 0, 4, A_BOLD, " Warning ");
  1546. X        mvwattrstr(e_win, 5, 22, A_BLINK, "Press any key to continue");
  1547. X        wmove(e_win, 5, 48);
  1548. X    }
  1549. X    beep();
  1550. X    wrefresh(e_win);
  1551. X
  1552. X    wgetch(e_win);
  1553. X    werase(e_win);
  1554. X    wrefresh(e_win);
  1555. X    delwin(e_win);
  1556. X
  1557. X    if (code) {
  1558. X        st_line("   exiting");
  1559. X        cleanup(code);
  1560. X    }
  1561. X    return;
  1562. X}
  1563. SHAR_EOF
  1564. if test 2504 -ne "`wc -c < 'pexit.c'`"
  1565. then
  1566.     echo shar: "error transmitting 'pexit.c'" '(should have been 2504 characters)'
  1567. fi
  1568. fi
  1569. echo shar: "extracting 'port.c'" '(9459 characters)'
  1570. if test -f 'port.c'
  1571. then
  1572.     echo shar: "will not over-write existing file 'port.c'"
  1573. else
  1574. sed 's/^X//' << \SHAR_EOF > 'port.c'
  1575. X/*
  1576. X * Routines to get or release a TTY port.
  1577. X */
  1578. X
  1579. X#define MAX_PID 30000
  1580. X
  1581. X#include <stdio.h>
  1582. X#include <fcntl.h>
  1583. X#include <termio.h>
  1584. X#include <errno.h>
  1585. X#include "config.h"
  1586. X#ifdef UNIXPC
  1587. X#include <sys/phone.h>
  1588. X#endif /* UNIXPC */
  1589. X#include "dial_dir.h"
  1590. X#include "modem.h"
  1591. X
  1592. Xstatic int getty_status;
  1593. Xstatic char *lock_path = NULL;
  1594. X/*
  1595. X * Finds a free (or requested) serial port.  Creates a lock file to hold
  1596. X * for our use.  Loads the modem database.  A return code of 1 means
  1597. X * all ports (or the requested port) are busy.
  1598. X */
  1599. X
  1600. Xint
  1601. Xget_port()
  1602. X{
  1603. X    extern int fd;
  1604. X    register int i;
  1605. X    int j, k, lfd, list[NUM_TTY], cmask, tbaud;
  1606. X    char file[80], buf[80], message[80], *strdup();
  1607. X    unsigned int sleep();
  1608. X    void error_win(), line_set(), release_port(), send_str();
  1609. X    void free_ptr();
  1610. X#ifndef ASCII_PID
  1611. X    int progpid;
  1612. X#endif /* ASCII_PID */
  1613. X
  1614. X    /*
  1615. X     * If we already have a port, see if it is good enough for the
  1616. X     * current request.
  1617. X     */
  1618. X#ifdef KEEP_PORT
  1619. X    if (fd != -1) {
  1620. X        if (!strcmp(dir->index[dir->d_cur], modem->tty[modem->t_cur]) ||
  1621. X         ck_speed(modem->t_cur, dir->baud[dir->d_cur])) {
  1622. X            /*
  1623. X             * Reset the line because the baud rate (or other
  1624. X             * parameters) may have changed.
  1625. X             */
  1626. X            line_set();
  1627. X            return(0);
  1628. X        }
  1629. X    }
  1630. X#endif /* KEEP_PORT */
  1631. X    release_port(1);
  1632. X
  1633. X    list[0] = -1;
  1634. X    /*
  1635. X     * See if you want a specific TTY port.  If the index field in the
  1636. X     * dialing directory is a valid device name, then use that TTY.
  1637. X     */
  1638. X    if (*dir->index[dir->d_cur] != NULL) {
  1639. X        sprintf(buf, "/dev/%s", dir->index[dir->d_cur]);
  1640. X                    /* if index is a valid device */
  1641. X        if (!access(buf, 0)) {
  1642. X            for (i=0; i<modem->t_entries; i++) {
  1643. X                    /* and it exists in modem database */
  1644. X                if (!strcmp(dir->index[dir->d_cur], modem->tty[i])) {
  1645. X                    list[0] = i;
  1646. X                    list[1] = -1;
  1647. X                    break;
  1648. X                }
  1649. X            }
  1650. X        }
  1651. X    }
  1652. X
  1653. X    /*
  1654. X     * Create a list of acceptable TTYs.  It searches the modem database
  1655. X     * for the requested baud rate.
  1656. X     */
  1657. X    k = 0;
  1658. X    if (list[0] == -1) {
  1659. X        for (i=0; i<modem->t_entries; i++) {
  1660. X                    /* skip ports with no modems */
  1661. X            if (!strcmp(modem->tname[i], "DIRECT"))
  1662. X                continue;
  1663. X
  1664. X                    /* can handle requested baud rate? */
  1665. X            if (ck_speed(i, dir->baud[dir->d_cur]))
  1666. X                list[k++] = i;
  1667. X        }
  1668. X                    /* the end of list marker */
  1669. X        list[k] = -1;
  1670. X    }
  1671. X                    /* empty list? */
  1672. X    if (list[0] == -1) {
  1673. X        sprintf(message, "No modem at a %d baud rating exists in the", dir->baud[dir->d_cur]);
  1674. X        sprintf(buf, "modem database '%s'", modem->m_path);
  1675. X        error_win(0, message, buf);
  1676. X        return(1);
  1677. X    }
  1678. X                    /* check the list for a free port */
  1679. X    i = 0;
  1680. X    while (list[i] != -1) {
  1681. X                    /* create a lock file name */
  1682. X        sprintf(file, "%s/LCK..%s", LOCK_DIR, modem->tty[list[i]]);
  1683. X#ifdef DEBUG
  1684. X        fprintf(stderr, "get_port: checking '/dev/%s'\n", modem->tty[list[i]]);
  1685. X#endif /* DEBUG */
  1686. X
  1687. X                    /* does it exist or is it dead? */
  1688. X        if (checklock(file)) {
  1689. X            getty_status = set_getty(modem->tty[list[i]], 0);
  1690. X
  1691. X            cmask = umask(0);
  1692. X            if ((lfd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0666)) < 0) {
  1693. X                if (getty_status)
  1694. X                    set_getty(modem->tty[list[i]], 1);
  1695. X                sprintf(buf, "'%s'", file);
  1696. X                error_win(1, "Can't create the lockfile", buf);
  1697. X            }
  1698. X            umask(cmask);
  1699. X#ifdef ASCII_PID
  1700. X            sprintf(buf, "%10d\n", getpid());
  1701. X            write(lfd, buf, 11);
  1702. X#else /* ASCII_PID */
  1703. X            progpid = getpid();
  1704. X            write(lfd, (char *) &progpid, sizeof(int));
  1705. X#endif /* ASCII_PID */
  1706. X            close(lfd);
  1707. X                    /* store the new values */
  1708. X            free_ptr(lock_path);
  1709. X            lock_path = strdup(file);
  1710. X            modem->t_cur = list[i];
  1711. X
  1712. X                    /* open the device (ignore DCD) */
  1713. X            sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]);
  1714. X            if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
  1715. X                if (getty_status)
  1716. X                    set_getty(modem->tty[modem->t_cur], 1);
  1717. X                sprintf(file, "Can't open port '%s' for read and write", buf);
  1718. X                error_win(1, file, "");
  1719. X            }
  1720. X                    /* turn off the "no delay" mode */
  1721. X            fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);
  1722. X                    /* change line settings */
  1723. X            line_set();
  1724. X                    /* load the modem data base */
  1725. X            modem->m_cur = -1;
  1726. X            for (j=0; j<modem->m_entries; j++) {
  1727. X                if (!strcmp(modem->tname[modem->t_cur], modem->mname[j])) {
  1728. X                    modem->m_cur = j;
  1729. X                    break;
  1730. X                }
  1731. X            }
  1732. X            if (modem->m_cur == -1) {
  1733. X                sprintf(buf, "Modem name '%s' in TTY database",
  1734. X                 modem->tname[modem->t_cur]);
  1735. X                error_win(1, buf, "does not exist in modem database");
  1736. X            }
  1737. X                    /* initialize the modem */
  1738. X            if (modem->init_sp[modem->t_cur]) {
  1739. X                tbaud = dir->baud[dir->d_cur];
  1740. X                dir->baud[dir->d_cur] = modem->init_sp[modem->t_cur];
  1741. X                line_set();
  1742. X                send_str(modem->init[modem->m_cur]);
  1743. X                dir->baud[dir->d_cur] = tbaud;
  1744. X            }
  1745. X            else
  1746. X                send_str(modem->init[modem->m_cur]);
  1747. X            sleep(1);
  1748. X            return(0);
  1749. X        }
  1750. X        i++;
  1751. X    }
  1752. X    error_win(0, "All ports are busy now, try again later", "");
  1753. X    return(1);
  1754. X}
  1755. X
  1756. X/*
  1757. X * Release the port.  Closes the file descriptor and removes the
  1758. X * lock file
  1759. X */
  1760. X
  1761. Xvoid
  1762. Xrelease_port(verbose)
  1763. Xint verbose;
  1764. X{
  1765. X    extern int fd;
  1766. X    extern char *null_ptr;
  1767. X    char buf[80];
  1768. X    void free_ptr(), hang_up();
  1769. X
  1770. X    /*
  1771. X     * The modem structure can't be guaranteed to exist yet.  For example,
  1772. X     * an error in reading one of the other support files would cause
  1773. X     * this routine to be used before the MODEM structure gets allocated.
  1774. X     */
  1775. X    if (modem == NULL)
  1776. X        return;
  1777. X                    /* close the port */
  1778. X    if (fd != -1) {
  1779. X        ioctl(fd, TCFLSH, 2);
  1780. X        /*
  1781. X         * Since HUPCL is set, the close() should drop the DTR and
  1782. X         * hang up the modem (provided you've got the modem to
  1783. X         * respond to DTR).  Since this is not guaranteed, we send
  1784. X         * the hang_up string first.
  1785. X         */
  1786. X        hang_up(verbose);
  1787. X        close(fd);
  1788. X    }
  1789. X                    /* remove the lock */
  1790. X    if (*lock_path != NULL && lock_path != NULL) {
  1791. X        if (unlink(lock_path)) {
  1792. X            sprintf(buf, "'%s'", lock_path);
  1793. X            error_win(0, "Can't remove the lock file", buf);
  1794. X        }
  1795. X        free_ptr(lock_path);
  1796. X        lock_path = null_ptr;
  1797. X    }
  1798. X                    /* turn the getty back on? */
  1799. X    if (getty_status)
  1800. X        set_getty(modem->tty[modem->t_cur], 1);
  1801. X                    /* clean up the structure */
  1802. X    fd = -1;
  1803. X    modem->m_cur = -1;
  1804. X    modem->t_cur = -1;
  1805. X    return;
  1806. X}
  1807. X
  1808. X/*
  1809. X * Turn the /etc/getty on or off for the specified port.  A return code
  1810. X * of 1 means that the getty was on.  Systems with uugetty() or dedicated
  1811. X * dialout ports won't need this routine.
  1812. X */
  1813. X
  1814. X/*ARGSUSED*/
  1815. Xstatic int
  1816. Xset_getty(tty, on)
  1817. Xchar *tty;
  1818. Xint on;
  1819. X{
  1820. X#ifdef UNIXPC
  1821. X    int i, ret_code;
  1822. X    char buf[40];
  1823. X    unsigned int sleep();
  1824. X                    /* the last three characters */
  1825. X    i = strlen(tty) -3;
  1826. X
  1827. X    ret_code = 0;
  1828. X    if (on) {
  1829. X        sprintf(buf, "setgetty %s 1", tty+i);
  1830. X        system(buf);
  1831. X    }
  1832. X    else {
  1833. X        sprintf(buf, "setgetty %s 0", tty+i);
  1834. X        if (system(buf) == 512)
  1835. X            ret_code++;
  1836. X        sleep(1);
  1837. X    }
  1838. X    return(ret_code);
  1839. X#else /* UNIXPC */
  1840. X    /*
  1841. X     * If you don't have one of these cute little routines, you
  1842. X     * might wanna write one.  It should check for an existing lock
  1843. X     * file, edit the /etc/inittab file, and issue an init -q.
  1844. X     * The return code should tell if there was a getty or not.
  1845. X     * Obviously the program would be suid to root.
  1846. X     */
  1847. X    return(0);
  1848. X#endif /* UNIXPC */
  1849. X}
  1850. X
  1851. X/*
  1852. X * Check the lock file for a valid pid value.  Error conditions such
  1853. X * as not being able to open the lock file or not being able to interpret
  1854. X * the contents of the lock file cause the code to assume that the lock
  1855. X * file is valid.  Let the user worry about weird special cases.  A return
  1856. X * code of 1 means the lock is dead or doesn't exist.
  1857. X */
  1858. X
  1859. Xstatic int
  1860. Xchecklock(lockfile)
  1861. Xchar *lockfile;
  1862. X{
  1863. X    extern int errno;
  1864. X    int lfd, lckpid;
  1865. X#ifdef ASCII_PID
  1866. X    int n;
  1867. X    char buf[40];
  1868. X#endif /* ASCII_PID */
  1869. X                    /* doesn't exist */
  1870. X    if (access(lockfile, 0))
  1871. X        return(1);
  1872. X                    /* can't open the lock file */
  1873. X    if ((lfd = open(lockfile, 0)) < 0)
  1874. X        return(0);
  1875. X
  1876. X#ifdef ASCII_PID
  1877. X    if ((n = read(lfd, buf, 40)) <= 0) {
  1878. X        close(lfd);
  1879. X        return(0);
  1880. X    }
  1881. X    close(lfd);
  1882. X    buf[n--] = '\0';
  1883. X    lckpid = atoi(buf);
  1884. X#else /* ASCII_PID */
  1885. X    if (read(lfd, (char *) &lckpid, sizeof(int)) != sizeof(int)) {
  1886. X        close(lfd);
  1887. X        return(0);
  1888. X    }
  1889. X    close(lfd);
  1890. X#endif /* ASCII_PID */
  1891. X                    /* invalid pid? */
  1892. X    if (lckpid <= 0 || lckpid > MAX_PID)
  1893. X        return(0);
  1894. X
  1895. X    if ((kill(lckpid, 0) == -1) && (errno == ESRCH)) {
  1896. X        /*
  1897. X         * If the kill was unsuccessful due to an ESRCH error,
  1898. X         * that means the process is no longer active and the
  1899. X         * lock file can be safely removed.
  1900. X         */
  1901. X        unlink(lockfile);
  1902. X        sleep(1);
  1903. X        return(1);
  1904. X    }
  1905. X    /*
  1906. X     * If the kill() was successful, that means the process must
  1907. X     * still active.
  1908. X     */
  1909. X    return(0);
  1910. X}
  1911. X
  1912. X/*
  1913. X * Check to see if the desired baud rate can be handled by the modem.
  1914. X * Uses the connect strings to make this determination.  The first
  1915. X * argument is the index into the TTY database.  A return code of 1
  1916. X * means yes.
  1917. X */
  1918. X
  1919. Xstatic int
  1920. Xck_speed(tty, baud)
  1921. Xint tty, baud;
  1922. X{
  1923. X    int i, mod;
  1924. X    char buf[60];
  1925. X                    /* find the modem database */
  1926. X    mod = -1;
  1927. X    for (i=0; i<modem->m_entries; i++) {
  1928. X        if (!strcmp(modem->mname[i], modem->tname[tty])) {
  1929. X            mod = i;
  1930. X            break;
  1931. X        }
  1932. X    }
  1933. X    if (mod == -1) {
  1934. X        sprintf(buf, "Modem name '%s' in TTY database", modem->tname[tty]);
  1935. X        error_win(1, buf, "does not exist in modem database");
  1936. X    }
  1937. X#ifdef DEBUG
  1938. X    fprintf(stderr, "ck_speed: checking modem '%s' for %d buad\n", modem->mname[mod], baud);
  1939. X#endif /* DEBUG */
  1940. X
  1941. X    switch (baud) {
  1942. X        case 300:
  1943. X            if (*modem->con_3[mod] != NULL)
  1944. X                return(1);
  1945. X            break;
  1946. X        case 1200:
  1947. X            if (*modem->con_12[mod] != NULL)
  1948. X                return(1);
  1949. X            break;
  1950. X        case 2400:
  1951. X            if (*modem->con_24[mod] != NULL)
  1952. X                return(1);
  1953. X            break;
  1954. X        case 4800:
  1955. X            if (*modem->con_48[mod] != NULL)
  1956. X                return(1);
  1957. X            break;
  1958. X        case 9600:
  1959. X            if (*modem->con_96[mod] != NULL)
  1960. X                return(1);
  1961. X            break;
  1962. X        case 19200:
  1963. X            if (*modem->con_192[mod] != NULL)
  1964. X                return(1);
  1965. X            break;
  1966. X    }
  1967. X    return(0);
  1968. X}
  1969. SHAR_EOF
  1970. if test 9459 -ne "`wc -c < 'port.c'`"
  1971. then
  1972.     echo shar: "error transmitting 'port.c'" '(should have been 9459 characters)'
  1973. fi
  1974. fi
  1975. echo shar: "extracting 'redial.c'" '(2242 characters)'
  1976. if test -f 'redial.c'
  1977. then
  1978.     echo shar: "will not over-write existing file 'redial.c'"
  1979. else
  1980. sed 's/^X//' << \SHAR_EOF > 'redial.c'
  1981. X/*
  1982. X * The redial option (actually a misnomer, it's really a queuing system).
  1983. X * We expect a space-separated list of dialing directory entries (although
  1984. X * new users always try to put in a phone number).  A non-zero return code
  1985. X * means we're ready to dial.
  1986. X */
  1987. X
  1988. X#include <stdio.h>
  1989. X#include <curses.h>
  1990. X#include "config.h"
  1991. X#include "dial_dir.h"
  1992. X#include "misc.h"
  1993. X
  1994. Xint
  1995. Xredial()
  1996. X{
  1997. X    extern int fd;
  1998. X    WINDOW *rd_win, *newwin();
  1999. X    char *ans, *entry, *get_str(), *strchr(), *strtok();
  2000. X    int i, oops, number, ret_code;
  2001. X
  2002. X    rd_win = newwin(6, 70, 5, 5);
  2003. X
  2004. X    mvwaddstr(rd_win, 4, 23, "(<CR> for previous numbers)");
  2005. X    mvwaddstr(rd_win, 2, 4, "Directory Entry Number(s): ");
  2006. X    box(rd_win, VERT, HORZ);
  2007. X
  2008. X    mvwattrstr(rd_win, 0, 3, A_BOLD, " Redial Queue ");
  2009. X    wmove(rd_win, 2, 31);
  2010. X    wrefresh(rd_win);
  2011. X                    /* get the string of numbers */
  2012. X    ret_code = 0;
  2013. X    while ((ans = get_str(rd_win, 35, "0123456789+-@# ", "")) != NULL) {
  2014. X        oops = 0;
  2015. X        if (*ans == NULL) {
  2016. X                    /* use previous queue */
  2017. X            if (dir->q_num[0] != -1) {
  2018. X                ret_code++;
  2019. X                break;
  2020. X            }
  2021. X                    /* there is no previous queue */
  2022. X            beep();
  2023. X            mvwattrstr(rd_win, 3, 4, A_BOLD, "No previous numbers");
  2024. X            wrefresh(rd_win);
  2025. X            wait_key(rd_win, 3);
  2026. X            clear_line(rd_win, 3, 4, 1);
  2027. X            wmove(rd_win, 2, 31);
  2028. X            wrefresh(rd_win);
  2029. X            continue;
  2030. X        }
  2031. X                    /* parse the queue values */
  2032. X        entry = strtok(ans, "     ");
  2033. X        for (i=0; i<NUM_QUEUE; i++) {
  2034. X            if (*entry == NULL) {
  2035. X                dir->q_num[i] = -1;
  2036. X                continue;
  2037. X            }
  2038. X                    /* is there a LD code? */
  2039. X            dir->q_ld[i] = NULL;
  2040. X            if (strchr("+-@#", *entry)) {
  2041. X                dir->q_ld[i] = *entry;
  2042. X                entry++;
  2043. X            }
  2044. X
  2045. X            /*
  2046. X             * Zero is valid here, because it means use
  2047. X             * the current entry information.
  2048. X             */
  2049. X            number = atoi(entry);
  2050. X            if (number < -1 || number > NUM_DIR) {
  2051. X                beep();
  2052. X                mvwattrstr(rd_win, 3, 4, A_BOLD, "Invalid directory entry number");
  2053. X                wrefresh(rd_win);
  2054. X                wait_key(rd_win, 3);
  2055. X                clear_line(rd_win, 3, 4, 1);
  2056. X                clear_line(rd_win, 2, 31, 1);
  2057. X                wrefresh(rd_win);
  2058. X                oops++;
  2059. X                break;
  2060. X            }
  2061. X                    /* store the number in the queue */
  2062. X            dir->q_num[i] = number;
  2063. X            entry = strtok((char *) NULL, "     ");
  2064. X        }
  2065. X        if (oops)
  2066. X            continue;
  2067. X        ret_code++;
  2068. X        break;
  2069. X    }
  2070. X    if (fd == -1) {
  2071. X        werase(rd_win);
  2072. X        wrefresh(rd_win);
  2073. X    }
  2074. X    delwin(rd_win);
  2075. X    return(ret_code);
  2076. X}
  2077. SHAR_EOF
  2078. if test 2242 -ne "`wc -c < 'redial.c'`"
  2079. then
  2080.     echo shar: "error transmitting 'redial.c'" '(should have been 2242 characters)'
  2081. fi
  2082. fi
  2083. exit 0
  2084. #    End of shell archive
  2085.  
  2086. -- 
  2087. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  2088.